using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// UI组。
/// </summary>
public sealed class UIGroup : MonoBehaviour, IUIGroup
{
    private string m_Name;
    private int m_Depth;
    private bool m_Pause;
    private readonly List<IUIForm> m_UIForms = new List<IUIForm>();
    private IUIGroupHelper m_Helper;

    /// <summary>
    /// 获取UI组名称。
    /// </summary>
    public string Name
    {
        get
        {
            return m_Name;
        }
    }

    /// <summary>
    /// 获取或设置UI组深度。
    /// </summary>
    public int Depth
    {
        get
        {
            return m_Depth;
        }
        set
        {
            if (m_Depth == value)
            {
                return;
            }

            m_Depth = value;
            SetDepth(m_Depth);
            Refresh();
        }
    }

    /// <summary>
    /// 获取或设置UI组是否暂停。
    /// </summary>
    public bool Pause
    {
        get
        {
            return m_Pause;
        }
        set
        {
            if (m_Pause == value)
            {
                return;
            }

            m_Pause = value;
            Refresh();
        }
    }

    /// <summary>
    /// 获取UI组中界面数量。
    /// </summary>
    public int UIFormCount
    {
        get
        {
            return m_UIForms.Count;
        }
    }

    /// <summary>
    /// 获取当前界面。
    /// </summary>
    public IUIForm CurrentUIForm
    {
        get
        {
            return m_UIForms.Count > 0 ? m_UIForms[m_UIForms.Count - 1] : null;
        }
    }

    /// <summary>
    /// 获取UI组辅助器。
    /// </summary>
    public IUIGroupHelper Helper
    {
        get
        {
            return m_Helper;
        }
    }

    /// <summary>
    /// 初始化UI组。
    /// </summary>
    /// <param name="name">UI组名称。</param>
    /// <param name="depth">UI组深度。</param>
    /// <param name="uiGroupHelper">UI组辅助器。</param>
    public void Initialize(string name, int depth, IUIGroupHelper uiGroupHelper)
    {
        if (string.IsNullOrEmpty(name))
        {
            Logger.LogError("UI group name is invalid.");
            return;
        }

        m_Name = name;
        m_Pause = false;
        m_Helper = uiGroupHelper;
        Depth = depth;
    }

    /// <summary>
    /// 界面是否存在。
    /// </summary>
    /// <param name="serialId">界面序列编号。</param>
    /// <returns>界面是否存在。</returns>
    public bool HasUIForm(int serialId)
    {
        for (int i = 0; i < m_UIForms.Count; i++)
        {
            if (m_UIForms[i].SerialId == serialId)
            {
                return true;
            }
        }

        return false;
    }

    /// <summary>
    /// 界面是否存在。
    /// </summary>
    /// <param name="uiFormAssetName">界面资源名称。</param>
    /// <returns>界面是否存在。</returns>
    public bool HasUIForm(string uiFormAssetName)
    {
        if (string.IsNullOrEmpty(uiFormAssetName))
        {
            return false;
        }

        for (int i = 0; i < m_UIForms.Count; i++)
        {
            if (m_UIForms[i].UIFormAssetName == uiFormAssetName)
            {
                return true;
            }
        }

        return false;
    }

    /// <summary>
    /// 从UI组中获取界面。
    /// </summary>
    /// <param name="serialId">界面序列编号。</param>
    /// <returns>要获取的界面。</returns>
    public IUIForm GetUIForm(int serialId)
    {
        for (int i = 0; i < m_UIForms.Count; i++)
        {
            if (m_UIForms[i].SerialId == serialId)
            {
                return m_UIForms[i];
            }
        }

        return null;
    }

    /// <summary>
    /// 从UI组中获取界面。
    /// </summary>
    /// <param name="uiFormAssetName">界面资源名称。</param>
    /// <returns>要获取的界面。</returns>
    public IUIForm GetUIForm(string uiFormAssetName)
    {
        if (string.IsNullOrEmpty(uiFormAssetName))
        {
            return null;
        }

        for (int i = m_UIForms.Count - 1; i >= 0; i--)
        {
            if (m_UIForms[i].UIFormAssetName == uiFormAssetName)
            {
                return m_UIForms[i];
            }
        }

        return null;
    }

    /// <summary>
    /// 从UI组中获取界面。
    /// </summary>
    /// <param name="uiFormAssetName">界面资源名称。</param>
    /// <returns>要获取的界面。</returns>
    public IUIForm[] GetUIForms(string uiFormAssetName)
    {
        if (string.IsNullOrEmpty(uiFormAssetName))
        {
            return new IUIForm[0];
        }

        List<IUIForm> results = new List<IUIForm>();
        for (int i = 0; i < m_UIForms.Count; i++)
        {
            if (m_UIForms[i].UIFormAssetName == uiFormAssetName)
            {
                results.Add(m_UIForms[i]);
            }
        }

        return results.ToArray();
    }

    /// <summary>
    /// 从UI组中获取界面。
    /// </summary>
    /// <param name="uiFormAssetName">界面资源名称。</param>
    /// <param name="results">要获取的界面。</param>
    public void GetUIForms(string uiFormAssetName, List<IUIForm> results)
    {
        if (results == null)
        {
            Logger.LogError("Results is invalid.");
            return;
        }

        results.Clear();
        if (string.IsNullOrEmpty(uiFormAssetName))
        {
            return;
        }

        for (int i = 0; i < m_UIForms.Count; i++)
        {
            if (m_UIForms[i].UIFormAssetName == uiFormAssetName)
            {
                results.Add(m_UIForms[i]);
            }
        }
    }

    /// <summary>
    /// 从UI组中获取所有界面。
    /// </summary>
    /// <returns>UI组中的所有界面。</returns>
    public IUIForm[] GetAllUIForms()
    {
        return m_UIForms.ToArray();
    }

    /// <summary>
    /// 从UI组中获取所有界面。
    /// </summary>
    /// <param name="results">UI组中的所有界面。</param>
    public void GetAllUIForms(List<IUIForm> results)
    {
        if (results == null)
        {
            Logger.LogError("Results is invalid.");
            return;
        }

        results.Clear();
        for (int i = 0; i < m_UIForms.Count; i++)
        {
            results.Add(m_UIForms[i]);
        }
    }

    /// <summary>
    /// 往UI组增加界面。
    /// </summary>
    /// <param name="uiForm">要增加的界面。</param>
    public void AddUIForm(IUIForm uiForm)
    {
        if (uiForm == null)
        {
            Logger.LogError("UI form is invalid.");
            return;
        }

        if (m_UIForms.Contains(uiForm))
        {
            return;
        }

        m_UIForms.Add(uiForm);
        Refresh();
    }

    /// <summary>
    /// 从UI组移除界面。
    /// </summary>
    /// <param name="uiForm">要移除的界面。</param>
    public void RemoveUIForm(IUIForm uiForm)
    {
        if (uiForm == null)
        {
            Logger.LogError("UI form is invalid.");
            return;
        }

        if (!m_UIForms.Remove(uiForm))
        {
            return;
        }

        Refresh();
    }

    /// <summary>
    /// 激活UI界面（将界面移到UI组顶部）。
    /// </summary>
    /// <param name="uiForm">要激活的界面。</param>
    public void RefocusUIForm(IUIForm uiForm)
    {
        if (uiForm == null)
        {
            Logger.LogError("UI form is invalid.");
            return;
        }

        if (!m_UIForms.Contains(uiForm))
        {
            return;
        }

        // 将界面移到列表末尾（顶部）
        m_UIForms.Remove(uiForm);
        m_UIForms.Add(uiForm);
        Refresh();
    }

    /// <summary>
    /// 刷新UI组。
    /// </summary>
    public void Refresh()
    {
        int depth = m_Depth;
        for (int i = 0; i < m_UIForms.Count; i++)
        {
            IUIForm uiForm = m_UIForms[i];
            if ((uiForm.Handle as MonoBehaviour) == null)
            {
                continue;
            }

            int uiFormDepth = depth + i;
            uiForm.OnDepthChanged(uiGroupDepth: m_Depth, depthInUIGroup: uiFormDepth);
        }
    }

    /// <summary>
    /// 设置深度。
    /// </summary>
    /// <param name="depth">深度。</param>
    private void SetDepth(int depth)
    {
        if (m_Helper != null)
        {
            m_Helper.SetDepth(depth);
        }
    }
}

